﻿using System;
using System.Text.RegularExpressions;

namespace Yz.Core.Extensions
{
    public static class ValidateExtension
    {

        #region 手机号验证 
        /// <summary>
        /// 判断一个字符串是否为电话号码
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsTelephone(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            return new Regex(@"^(86)?(-)?(0\d{2,3})?(-)?(\d{7,8})(-)?(\d{3,5})?$", RegexOptions.IgnoreCase).Match(value).Success;
        }
        /// <summary>
        ///     判断一个字符串是否为手机号码
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public static bool IsMobilePhone(this string value)
        {
            //电信手机号码正则
            string dianXin = @"^1[3578][01379]\d{8}$";
            Regex regexDX = new Regex(dianXin);
            //联通手机号码正则
            string lianTong = @"^1[34578][01256]\d{8}";
            Regex regexLT = new Regex(lianTong);
            //移动手机号码正则
            string yiDong = @"^(1[012345678]\d{8}|1[345678][012356789]\d{8})$";
            Regex regexYD = new Regex(yiDong);
            if (regexDX.IsMatch(value) || regexLT.IsMatch(value) || regexYD.IsMatch(value))
            {
                return true;
            }
            return false;
        }
        #endregion

        #region 数值判断
        /// <summary>
        /// 检查一个字符串是否是纯数字构成的，一般用于查询字符串参数的有效性验证。
        /// </summary>
        /// <param name="value">需验证的字符串。。</param>
        /// <returns>是否合法的bool值。</returns>
        public static bool IsNumeric(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            return new Regex("^[1-9]*[0-9]*$").IsMatch(value);
        }
        /// <summary>
        /// 判断一个字符串是否为Int
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsInt(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            Regex regex = new Regex(@"^(-){0,1}\d+$");
            if (regex.Match(value).Success)
            {
                if ((long.Parse(value) > 0x7fffffffL) || (long.Parse(value) < -2147483648L))
                {
                    return false;
                }
                return true;
            }
            return false;
        }
        /// <summary>
        /// 是否是浮点数 可带正负号
        /// </summary>
        /// <param name="inputData">输入字符串</param>
        /// <returns></returns>
        public static bool IsDecimal(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            return new Regex("^[+-]?[0-9]+[.]?[0-9]+$").Match(value).Success;
        }
        #endregion

        #region Url判断
        /// <summary>
        /// 判断一个字符串是否为网址
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsUrl(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            return new Regex(@"([http|https]://)?([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?", RegexOptions.IgnoreCase).Match(value).Success;
        }
        #endregion 

        #region 字符串判断
        /// <summary>
        /// 判断一个字符串是否为字母加数字
        /// Regex("[a-zA-Z0-9]?"
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsWordAndNum(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            return new Regex("[a-zA-Z0-9]?").Match(value).Success;
        }
        /// <summary>
        /// 检查输入的参数是不是某些定义好的特殊字符：这个方法目前用于密码输入的安全检查
        /// </summary>
        public static bool HasContainSpecChar(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            string[] list = new string[] { "123456", "654321" };
            bool result = new bool();
            for (int i = 0; i < list.Length; i++)
            {
                if (value == list[i])
                {
                    result = true;
                    break;
                }
            }
            return result;
        }
        /// <summary>
        /// 是否包含相同的字符
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool HasContainSameChar(this string value, string charValue)
        {
            if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(charValue) || charValue.Length != 1)
            {
                return false;
            }
            return new Regex(string.Format("^([{0}])+$", charValue)).Match(value).Success;
        }

        /// <summary>
        /// 检测是否有中文字符
        /// </summary>
        /// <param name="inputData"></param>
        /// <returns></returns>
        public static bool HasChZn(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            return new Regex("[\u4e00-\u9fa5]").Match(value).Success;
        }
        #endregion

        #region 身份证
        /// <summary>
        /// 判断一个字符串是否为ID格式
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsIDCard(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            Regex regex;
            string[] strArray;
            DateTime time;
            if ((value.Length != 15) && (value.Length != 0x12))
            {
                return false;
            }
            if (value.Length == 15)
            {
                regex = new Regex(@"^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$");
                if (!regex.Match(value).Success)
                {
                    return false;
                }
                strArray = regex.Split(value);
                try
                {
                    time = new DateTime(int.Parse("19" + strArray[2]), int.Parse(strArray[3]), int.Parse(strArray[4]));
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            regex = new Regex(@"^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9Xx])$");
            if (!regex.Match(value).Success)
            {
                return false;
            }
            strArray = regex.Split(value);
            try
            {
                time = new DateTime(int.Parse(strArray[2]), int.Parse(strArray[3]), int.Parse(strArray[4]));
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion

        #region 日期判断
        /// <summary>
        /// 检查一个字符串是否可以转化为日期，一般用于验证用户输入日期的合法性。
        /// </summary>
        /// <param name="value">需验证的字符串。</param>
        /// <returns>是否可以转化为日期的bool值。</returns>
        public static bool IsStringDate(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            DateTime dTime;
            try
            {
                dTime = DateTime.Parse(value);
            }
            catch
            {
                return false;
            }
            return true;
        }
        #endregion

        #region 邮箱判断
        /// <summary>
        /// 是否是浮点数 可带正负号
        /// </summary>
        /// <param name="inputData">输入字符串</param>
        /// <returns></returns>
        public static bool IsEmail(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            return new Regex("^[\\w-]+@[\\w-]+\\.(com|net|org|edu|mil|tv|biz|info)$").Match(value).Success;
        }

        #endregion

        #region 长度验证


        /// <summary>
        /// 验证字符串长度是否合法
        /// </summary>
        /// <param name="strText">验证字符串</param>
        /// <param name="maxlength">最大长度</param>
        /// <returns>不为空，且没有超出最大长度，返回True</returns>
        public static bool IsInLimit(this string strText, int maxlength = 0)
        {
            //是否为空
            bool isEmpty = String.IsNullOrWhiteSpace(strText);
            //是否超出最大长度
            bool exceedLength = false;
            if (!isEmpty && maxlength > 0)
            {
                exceedLength = strText.Length > maxlength;
            }
            return !exceedLength && !isEmpty;
        }
        #endregion 

        #region 判断空值
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value">值</param>
        public static bool IsEmpty(this string value)
        {
            return string.IsNullOrWhiteSpace(value);
        }
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value">值</param>
        public static bool IsEmpty(this Guid? value)
        {
            if (value == null)
                return true;
            return IsEmpty(value.Value);
        }
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value">值</param>
        public static bool IsEmpty(this Guid value)
        {
            if (value == Guid.Empty)
                return true;
            return false;
        }
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value">值</param>
        public static bool IsEmpty(this object value)
        {
            if (value != null && !string.IsNullOrEmpty(value.ToString()))
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        #endregion

        #region 银行卡判断
        /// <summary>
        /// 校验银行卡卡号
        /// </summary>
        /// <param name="cardId">卡号</param>
        /// <returns></returns>
        public static bool IsBankCard(this string cardId)
        {
            char bit = GetBankCardCheckCode(cardId.Substring(0, cardId.Length - 1));
            if (bit == 'N')
            {
                return false;
            }
            return cardId.CharAt(cardId.Length - 1).ToCharArray()[0] == bit;
        }

        /// <summary>
        /// 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
        /// </summary>
        /// <param name="nonCheckCodeCardId"></param>
        /// <returns></returns>
        private static char GetBankCardCheckCode(String nonCheckCodeCardId)
        {
            if (nonCheckCodeCardId == null || nonCheckCodeCardId.Trim().Length == 0
            || !Regex.Match(nonCheckCodeCardId, "\\d+").Success)// 如果传的不是数据返回N
            {
                return 'N';
            }
            char[] chs = nonCheckCodeCardId.Trim().ToCharArray();
            int luhmSum = 0;
            for (int i = chs.Length - 1, j = 0; i >= 0; i--, j++)
            {
                int k = chs[i] - '0';
                if (j % 2 == 0)
                {
                    k *= 2;
                    k = k / 10 + k % 10;
                }
                luhmSum += k;
            }
            return (luhmSum % 10 == 0) ? '0' : (char)((10 - luhmSum % 10) + '0');
        }

        public static string CharAt(this string s, int index)
        {
            if ((index >= s.Length) || (index < 0))
                return "";
            return s.Substring(index, 1);
        }
        #endregion 
    }
}
